<?php

/**
 * CollectionItem form.
 *
 * @package    travide
 * @subpackage form
 * @author     Travide Project Group
 * @version    SVN: $Id: sfDoctrineFormTemplate.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class CollectionItemForm extends BaseCollectionItemForm {
    var $propertiesForDeletion = array();
    var $relationsForDeletion = array();
    var $resourcesForDeletion = array();



    /**
     * Creates <numForms> blank forms for class <embedFormClass>
     * and embeds them in a parent form
     *
     * @param CLASS The class of form to add
     * @param string A base for the name of the forms
     * @param integer The number of blank forms  to add
     * @return <type> sfForm containing a the new subforms
     */
    private function createNewItemForms($embedFormClass, $nameBase, $numForms) {
        $newItemsForm = new sfForm();
        for($i = 0; $i < $numForms; $i++ ) {
            $newItemForm = new $embedFormClass();
            $newItemsForm->embedForm($nameBase.'_'.$i, $newItemForm);
        }

        return $newItemsForm;
    }

    /**
     * Configure this parent forms embedded forms for
     * Relations and Properties
     */
    private function configureEmbeddedForms() {
        $numNewEmbeddedForms = sfConfig::get('app_form_numNewEmbeddedForms',1);
        /**
         * Embed Relation for CollectionRelation and New Collection Relations
         */
        $this->embedRelation('CollectionRelations');

        /**
         * Do not include relating collections as a form item - jsut include as a
         * display item
         */
        //$this->embedRelation('RelatingCollections');

        $this->embedForm('NewCollectionRelation', $this->createNewItemForms('CollectionRelationForm', 'newCollectionRelation', sfConfig::get('app_collection_form_new_relations',1)));


        $this->embedRelation('CollectionProperties');

        /*This code section was created to allow for manual creation of the collection
         * properties forms - sadly these don't seem as useful as they did before
          * so this requirement is being pushed to the end of hte queue
           *         $collectionProperties = new sfForm();
        foreach ($this->getObject()->getCollectionProperties() as $index => $collectionProperty) {
            $collectionProperties->embedForm($index, new CollectionPropertyForm($collectionProperty));
        }

        $this->embedForm('CollectionProperties',$collectionProperties);
        */
        $this->embedForm('NewCollectionProperty',$this->createNewItemForms('CollectionPropertyForm','newCollectionProperty',sfConfig::get('app_collection_form_new_properties',1)));

        if (sfConfig::get('app_collection_enable_resources')) {
            $this->embedRelation('CollectionResources');


            $this->embedForm('NewCollectionResource',$this->createNewItemForms('CollectionResourceForm','newCollectionResource',sfConfig::get('app_collection_form_new_resources',1)));
        }


    }

    public function configure() {
        $this->configureEmbeddedForms();



        /**
         * Hide fields we don't want edited
         * Created_at, updated_At
         */
        unset($this['created_at'],$this['updated_at'],$this['deleted_at']);


        /**
         * Set Labels and Help text
         */
        $w = $this->getWidget('collectionTypeUin');
        $w->setLabel('Type');

        $w = $this->getWidget('visibilityLevelUin');
        $w->setLabel('Visibility');


        $w = new sfWidgetFormTextarea();
        $w->setLabel('Collection Name');
        $this->setWidget('collectionName', $w);

        /**
         * Add widget and validators for the TagString
         */
        $w = new sfWidgetFormTextarea();
        $w->setLabel('Tags');
        $w->setDefault($this->getObject()->getTagString());
        $this->setWidget('tagString',$w);
        $this->setValidator('tagString', new sfValidatorPass());

        $w = new sfWidgetFormInputText();
        $w->setLabel('Applicability Start');
        $w->setAttribute('class', 'dateSelect');
        $this->setWidget('applicableStart',$w);

        $w = new sfWidgetFormInputText();
        $w->setLabel('Applicability End');
        $w->setAttribute('class', 'dateSelect');
        $this->setWidget('applicableEnd',$w);
    }


    /**
     * Custom bind method to handle submision of forms with new
     * Properties or Relations
     *
     * @param array $taintedValues
     * @param array $taintedFiles
     */
    public function bind(array $taintedValues = null, array $taintedFiles = null) {
        /**
         * cycle throuhg all the new colleciton relations ignore any that
         * haven't had their relationType and relationItem fields set
         */
        if (isset($taintedValues['NewCollectionRelation'])) {
            foreach($taintedValues['NewCollectionRelation'] as $i => $newCollectionRelation) {
                /**
                 * if the user did not specify a relation type then ignore the
                 * collectionRelation
                 */
                if (is_null($newCollectionRelation['relationTypeUin']) ||
                        strlen($newCollectionRelation['relationTypeUin']) == 0 ) {
                    /**
                     * Remove the collectionRelation from the form
                     */

                    unset($taintedValues['NewCollectionRelation'][$i]);
                    unset($this->embeddedForms['NewCollectionRelation']->embeddedForms[$i]);
                    $this->validatorSchema['NewCollectionRelation'][$i]  = new sfValidatorPass();
                } else {
                    /**
                     * Set the thisCollectionUin to the current repository
                     */
                    $this->embeddedForms['NewCollectionRelation']->embeddedForms[$i]->getObject()->setThisItem($this->getObject());
                }
            }
        }

        /**
         * cycle throuhg all the new colleciton properties ignore any that
         * haven't had their PropertyValue field set
         */
        if (isset($taintedValues['NewCollectionProperty'])) {
            foreach($taintedValues['NewCollectionProperty'] as $i => $newCollectionProperty) {
                /**
                 * if the user did not specify a relation type then ignore the
                 * collectionProperty
                 */
                if (is_null($newCollectionProperty['propertyValue']) ||
                        strlen($newCollectionProperty['propertyValue']) == 0) {
                    /**
                     * Remove the collectionProperty from the form
                     */
                    unset($taintedValues['NewCollectionProperty'][$i]);
                    unset($this->embeddedForms['NewCollectionProperty']->embeddedForms[$i]);
                    $this->validatorSchema['NewCollectionProperty'][$i]  = new sfValidatorPass();
                } else {
                    /**
                     * Set the collectionUin to the current repository
                     */
                    $this->embeddedForms['NewCollectionProperty']->embeddedForms[$i]->getObject()->setCollectionItem($this->getObject());
                }
            }
        }



        /**
         * cycle through all the new collection resources ignore any that
         * haven't had their resourceName field set
         */
        if (isset($taintedValues['NewCollectionResource'])) {
            foreach($taintedValues['NewCollectionResource'] as $i => $newCollectionResource) {
                /**
                 * if the user did not specify a relation type then ignore the
                 * collectionProperty
                 */
                if (is_null($newCollectionResource['resourceName']) ||
                        strlen($newCollectionResource['resourceName']) == 0) {
                    /**
                     * Remove the collectionProperty from the form
                     */
                    unset($taintedValues['NewCollectionResource'][$i]);
                    unset($this->embeddedForms['NewCollectionResource']->embeddedForms[$i]);
                    $this->validatorSchema['NewCollectionResource'][$i]  = new sfValidatorPass();
                } else {
                    /**
                     * Set the collectionUin to the current repository
                     */
                    $this->embeddedForms['NewCollectionResource']->embeddedForms[$i]->getObject()->setCollectionItem($this->getObject());
                }
            }
        }

        /**
         * Find any properties marked for deletion and note them
         *
         */
        if (isset($taintedValues['CollectionProperties'])) {
            foreach($taintedValues['CollectionProperties'] as $i => $collectionProperty) {
                if (isset($collectionProperty['propertyDelete'])) {

                    $this->propertiesForDeletion[$i] = $collectionProperty['uin'];
                }
            }
        }

        /**
         * Find any relations marked for deletion and note them
         *
         */
        if (isset($taintedValues['CollectionRelations'])) {
            foreach($taintedValues['CollectionRelations'] as $i => $collectionRelation) {
                if (isset($collectionRelation['relationDelete'])) {
                    $this->relationsForDeletion[$i] = $collectionRelation['uin'];
                }
            }
        }

        /**
         * Find any resources marked for deletion and note them
         *
         */
        if (isset($taintedValues['CollectionResources'])) {
            foreach($taintedValues['CollectionResources'] as $i => $collectionResource) {
                if (isset($collectionResource['resourceDelete'])) {
                    $this->resourcesForDeletion[$i] = $collectionResource['uin'];
                }
            }
        }

        /**
         * contunue the bind tree to have the rest of the parameters bound
         * and checked
         */
        parent::bind($taintedValues,$taintedFiles);
    }



    /**
     * Override the doUpdateObject function to remove any properties,
     * relations, resources, etc that have been marked for deletion
     * (essentially - doesn't re-save them - marks them for deletion in
     * doctrine and then removes them from the embedded forms so it no longer
     * appears to doctrine as something that needs to be saved.
     *
     * @param <type> $values
     */
    protected function doUpdateObject($values) {


        if (count($this->propertiesForDeletion)) {
            foreach($this->propertiesForDeletion as $index => $uin) {
                unset($values['CollectionProperties'][$index]);
                unset($this->object['CollectionProperties'][$index]);
                unset($this->embeddedForms['CollectionProperties'][$index]);
                Doctrine::getTable('CollectionProperty')->find($uin)->delete();
            }
        }

        if (count($this->relationsForDeletion)) {
            foreach($this->relationsForDeletion as $index => $uin) {
                unset($values['CollectionRelations'][$index]);
                unset($this->object['CollectionRelations'][$index]);
                unset($this->embeddedForms['CollectionRelations'][$index]);
                Doctrine::getTable('CollectionRelation')->find($uin)->delete();
            }
        }

        if (count($this->resourcesForDeletion)) {
            foreach($this->resourcesForDeletion as $index => $uin) {
                unset($values['CollectionResources'][$index]);
                unset($this->object['CollectionResources'][$index]);
                unset($this->embeddedForms['CollectionResources'][$index]);
                Doctrine::getTable('CollectionResource')->find($uin)->delete();
            }
        }


        parent::doUpdateObject($values);


    }




}